﻿using System;
using System.Collections.Generic;
using System.Text;
using ActiproSoftware.SyntaxEditor;
using ActiproSoftware.SyntaxEditor.Addons.DotNet.Ast;

namespace WindowsUserControl.Codes
{
    /// <summary>
    /// Represents a binary expression.
    /// </summary>
    public class BinaryExpression : Expression
    {

        private OperatorType operatorType;

        /// <summary>
        /// Gets the context ID for the left expression affected by the binary operator.
        /// </summary>
        public const byte LeftExpressionContextID = Expression.ExpressionContextIDBase;

        /// <summary>
        /// Gets the context ID for the right expression affected by the binary operator.
        /// </summary>
        public const byte RightExpressionContextID = Expression.ExpressionContextIDBase + 1;

        /// <summary>
        /// Gets the minimum context ID that should be used in your code for AST nodes inheriting this class.
        /// </summary>
        /// <remarks>
        /// Base all your context ID constants off of this value.
        /// </remarks>
        protected const byte BinaryExpressionContextIDBase = Expression.ExpressionContextIDBase + 2;

        /////////////////////////////////////////////////////////////////////////////////////////////////////
        // OBJECT
        /////////////////////////////////////////////////////////////////////////////////////////////////////

        /// <summary>
        /// Initializes a new instance of the <c>BinaryExpression</c> class.
        /// </summary>
        /// <param name="operatorType">An <see cref="OperatorType"/> indicating the binary operator type.</param>
        /// <param name="leftExpression">The left <see cref="Expression"/> affected by the unary operator.</param>
        /// <param name="rightExpression">The right <see cref="Expression"/> affected by the unary operator.</param>
        /// <param name="textRange">The <see cref="TextRange"/> of the expression.</param>
        public BinaryExpression(OperatorType operatorType, Expression leftExpression, Expression rightExpression, TextRange textRange)
            : this(textRange)
        {
            // Initialize parameters
            this.operatorType = operatorType;
            this.LeftExpression = leftExpression;
            this.RightExpression = rightExpression;
        }

        /// <summary>
        /// Initializes a new instance of the <c>BinaryExpression</c> class. 
        /// </summary>
        public BinaryExpression() { }

        /// <summary>
        /// Initializes a new instance of the <c>BinaryExpression</c> class. 
        /// </summary>
        /// <param name="textRange">The <see cref="TextRange"/> of the AST node.</param>
        public BinaryExpression(TextRange textRange) : base(textRange) { }

        /////////////////////////////////////////////////////////////////////////////////////////////////////
        // PUBLIC PROCEDURES
        /////////////////////////////////////////////////////////////////////////////////////////////////////

        /// <summary>
        /// Accepts the specified visitor for visiting this node.
        /// </summary>
        /// <param name="visitor">The visitor to accept.</param>
        /// <remarks>This method is part of the visitor design pattern implementation.</remarks>
        protected override void AcceptCore(AstVisitor visitor)
        {
            if (visitor.OnVisiting(this))
            {
                // Visit children
                if (this.ChildNodeCount > 0)
                    this.AcceptChildren(visitor, this.ChildNodes);
            }
            visitor.OnVisited(this);
        }

        /// <summary>
        /// Gets the image index that is applicable for displaying this node in a user interface control.
        /// </summary>
        /// <value>The image index that is applicable for displaying this node in a user interface control.</value>
        public override int ImageIndex
        {
            get
            {
                return (System.Int32)ActiproSoftware.Products.SyntaxEditor.IconResource.Operator;
            }
        }

        /// <summary>
        /// Gets the <see cref="SimpleNodeType"/> that identifies the type of node.
        /// </summary>
        /// <value>The <see cref="SimpleNodeType"/> that identifies the type of node.</value>
        public override SimpleNodeType NodeType
        {
            get
            {
                return SimpleNodeType.BinaryExpression;
            }
        }

        /// <summary>
        /// Gets or sets the left expression affected by the binary operator.
        /// </summary>
        /// <value>The left expression affected by the binary operator.</value>
        public Expression LeftExpression
        {
            get
            {
                return this.GetChildNode(BinaryExpression.LeftExpressionContextID) as Expression;
            }
            set
            {
                this.ChildNodes.Replace(value, BinaryExpression.LeftExpressionContextID);
            }
        }

        /// <summary>
        /// Gets or sets the right expression affected by the binary operator.
        /// </summary>
        /// <value>The right expression affected by the binary operator.</value>
        public Expression RightExpression
        {
            get
            {
                return this.GetChildNode(BinaryExpression.RightExpressionContextID) as Expression;
            }
            set
            {
                this.ChildNodes.Replace(value, BinaryExpression.RightExpressionContextID);
            }
        }

        /// <summary>
        /// Gets or sets an operator type indicating the binary operator type.
        /// </summary>
        /// <value>An operator type indicating the binary operator type.</value>
        public OperatorType OperatorType
        {
            get
            {
                return operatorType;
            }
            set
            {
                operatorType = value;
            }
        }

        /// <summary>
        /// Gets text representing the node that can be used for display, such as in a document outline.
        /// </summary>
        /// <value>Text representing the node that can be used for display, such as in a document outline.</value>
        public override string DisplayText
        {
            get
            {
                return "Binary Expression " + this.OperatorType;
            }
        }

    }
}
